<?php
/**
 * User: taodf
 * Date: 17-4-29
 * Time: 下午9:02
 */

namespace Zeus\Routing\Engines;

use Zeus\Routing\RouterInterface;
use FastRoute\RouteParser\Std as FastRoutePaser;
use FastRoute\RouteCollector as FastRouteCollector;
use FastRoute\DataGenerator\GroupCountBased as FastRouteDataGenerator;
use FastRoute\Dispatcher\GroupCountBased as FastRouteDispatcher;

class FastRouteEngine implements RouterInterface
{

    /**
     * @var FastRouteCollector $collector;
     */
    private $collector;

    /**
     * @var FastRouteDispatcher $dispatcher
     */
    private $dispatcher;

    public function __construct()
    {
        $this->collector=new FastRouteCollector(
            new FastRoutePaser(), new FastRouteDataGenerator()
        );
    }

    /**
     * 向路由引擎中注册路由
     *
     * @param string|array $method
     * @param string $url
     * @param callable $callable
     */
    public function register($method, $url, $callable)
    {
        $this->collector->addRoute($method, $url, $callable);
    }

    /**
     * 注册GET方法路由
     *
     * @param string $url
     * @param callable $callable
     */
    public function get($url, $callable)
    {
        $this->register("GET", $url, $callable);
    }

    /**
     * 注册POST方法路由
     *
     * @param string $url
     * @param callable $callable
     */
    public function post($url, $callable)
    {
        $this->register("POST", $url, $callable);
    }

    /**
     * 注册PUT方法路由
     *
     * @param string $url
     * @param callable $callable
     */
    public function put($url, $callable)
    {
        $this->register("PUT", $url, $callable);
    }

    /**
     * 注册PATCH方法路由
     *
     * @param string $url
     * @param callable $callable
     */
    public function patch($url, $callable)
    {
        $this->register("PATCH", $url, $callable);
    }

    /**
     * 注册DELETE方法路由
     *
     * @param string $url
     * @param callable $callable
     */
    public function delete($url, $callable)
    {
        $this->register("DELETE", $url, $callable);
    }

    /**
     * 注册HEAD方法路由
     *
     * @param string $url
     * @param callable $callable
     */
    public function head($url, $callable)
    {
        $this->register("HEAD", $url, $callable);
    }

    /**
     * 根据请求，分发路由
     *
     * @param \Zeus\Http\Request $request
     * @param callable $handler
     * @return mixed
     */
    public function dispatch($request, $handler)
    {
        if(is_null($this->dispatcher)){
            $this->dispatcher=new FastRouteDispatcher($this->collector->getData());
        }
        $routeInfo=$this->dispatcher->dispatch(
            $request->getMethod(), $request->getRequestUri()
        );
        switch ($routeInfo[0]){
            case \FastRoute\Dispatcher::NOT_FOUND:
            case \FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
                call_user_func_array($handler, [
                    "handler"=>false,
                    "parameters"=>false
                ]);
                break;
            case \FastRoute\Dispatcher::FOUND:
                call_user_func_array($handler, [
                    "handler"=>$routeInfo[1],
                    "parameters"=>$routeInfo[2]
                ]);
                break;
            default:
                call_user_func_array($handler, [
                    "handler"=>false,
                    "parameters"=>false
                ]);
                break;
        }
    }

    /**
     * 路由的分组注册
     *
     * @param string $prefix
     * @param $callable
     * @return mixed
     */
    public function group($prefix, $callable)
    {
        $this->collector->addGroup($prefix, $callable);
    }
}